/*valgrind --leak-check=full --undef-value-errors=no --log-file=/home/utn_so/log.txt ./main*/


#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netdb.h>
#include <sys/un.h> 
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <netinet/in.h> 
#include <arpa/inet.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/ipc.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <sys/select.h>
#include <math.h>
#include <pthread.h>
#include <semaphore.h>

#include "estructuras.h"
#include "constantes.h"
#include "log.h"
#include "estadisticas.h"
#include "listas.h"
#include "sockets.h"
#include "configuracion.h"
#include "algoritmo.h"
#include "NIPC.h"
#include "recibirComando.h"


int	AgregarAColaDeConexionesPFS(listaPFS ** pnodo, listaPFS ** ListaDePFS);
int removerConexionDeListaPFS(listaPFS ** pnodo, listaPFS ** ListaDePFS);
void configToCHS();
chs getCHS(); 
void intacad ( int n , char* cadena); 
void * AtenderPFS(void * args);
void * AtenderPedido (void * SocketConectado); 
void * RecibirPedido (void * SocketConectado); 


chs glChs;
float RPM;
int sectores_totales_vda; 
char* algoritmo;
extern ListConfig * listaConfig;
extern pthread_mutex_t mutex;  
extern pthread_mutex_t mutex2; 
extern pthread_mutex_t mutex3; 
extern int activaEnAtencion;
int MODO;
int ALG;
t_log *logFile;
pthread_mutex_t mutexnumped = PTHREAD_MUTEX_INITIALIZER; 
colas2 cola2;
int numeroPedido; 

int main(int argc, char** argv)
{
	printf("%s",argv[1]);
	nDisco = atoi(argv[1]);
	char *aux;
	int i,len,t,fdmax;
	struct sockaddr_un local, remote;
	int iSocketDePedido;
	fd_set set_socketFSS;
	int iMayorSocket=0;
    pthread_t ID_HiloAtenderPedidos;
	pthread_t atenderConsola;
	int ret;
	struct sockaddr_in cliente;
	int address_size=sizeof(struct sockaddr_in);
	char *brkt;
	char sSocket[20];
	int sector_num;
	char id_Disco[20];
	char buffer[512];
	char buffer_sect[20];
	char buffer_id[20];
	char *algoritmo=(char *)malloc(20);
	char *modo=(char *)malloc(20);
	
	cola2.activacabeza=NULL;
	cola2.activacola=NULL;
	cola2.pasivacabeza=NULL;
	cola2.pasivacola=NULL;
	cola2.segundaPasadaActiva=NULL;
	cola2.segundaPasadaPasiva=NULL;
	
	/*Esto va si la conexion esta en modo LISTEN*/
	int iSocketCliente_temporal,iSocketEscuchaConexiones;
	/*char * sIDdescriptor_delPedido=(char *)malloc(20);*/
	/*********************************************/
			
	/*CONFIGURACIONES INICIALES*/
    listaConfig = NULL;
    cargarConfig(); 
	system("clear");	
	printf("\nCargando Archivo de Configuracion...\n\n");
    printf("Path_SocketConsola %s \n",obtenerValor("path"));
    strcpy(modo,obtenerValor("modo"));
	printf("Modo %s \n",modo);
	strcpy(algoritmo,obtenerValor("alg"));
	printf("Algoritmo %s \n",algoritmo);
    printf("Puerto %s \n",obtenerValor("puerto"));
    printf("Ip %s \n",obtenerValor("ip"));
    printf("Flag_Log %s \n",obtenerValor("flag_Log"));
    strcpy(id_Disco,obtenerValor("id_Disco"));
	printf("Id_Disco %s \n",id_Disco);
    escritura=atoi(obtenerValor("t_Escritura"));
	lectura=atoi(obtenerValor("t_Lectura"));
	printf("T_Lectura %i \n",lectura);
    printf("T_Escritura %i \n",escritura);
    printf("RPM %s \n",obtenerValor("RPM"));
	RPM=atof(obtenerValor("RPM"));
    printf("T_Salto %s \n",obtenerValor("t_Salto"));
	printf("ipRAID %s \n",obtenerValor("ipRAID"));
	printf("Puerto CONEXION RAID %s \n",obtenerValor("puertoRAID"));
	configToCHS();	
	printf("glChs.cilindros %i \n",glChs.cilindros);
	printf("glChs.cabezal %i \n",glChs.cabezal);
	printf("glChs.sectores %i \n",glChs.sectores);
	sectores_totales_vda = sectoresTotales(getCHS());
	printf("Los sectores totales son %i \n",sectores_totales_vda);
	posicionCabezal=0;
	initialize_disk();
	if (strcmp(algoritmo, "FSCAN") == 0)
		ALG=FSCAN;
	if (strcmp(algoritmo, "CLOOK") == 0)
		ALG=CLOOK;
	
	printf("ALG %i\n",ALG);
		
	if (strcmp(modo, "LISTEN") == 0)
		MODO=LISTEN;
	if (strcmp(modo, "CONNECT") == 0)
		MODO=CONNECT;	
	free(algoritmo);
	free(modo);
	logFile = log_create("PPD", "./log.txt",  WARNINGs | DEBUGs | ERRORs | INFOs, M_CONSOLE_DISABLE); /*Se crea al log*/
	
		  
	/*Hilo de consola
	ret=pthread_create(&atenderConsola,NULL, (void *)recibircomando,(void *)&cola2);
	if(ret!=0){
		perror("pthread_create");
		exit(EXIT_FAILURE);
	}
	*/
 
	/*Hilo para atencion de pedidos*/
 	ret=pthread_create(&ID_HiloAtenderPedidos,NULL,(void *)AtenderPedido,(void *)&cola2); 
	if(ret!=0){
		perror("pthread_create");
		exit(EXIT_FAILURE);
	}
	
	if (MODO == CONNECT){
		
		InfoIPC rInfoIPC44;
		iSocketConectado = crearSocket(AF_INET);
		Conectar2(iSocketConectado,obtenerValor("ipRAID"),atoi(obtenerValor("puertoRAID")));	
		rInfoIPC44.payLoadLength=strlen(id_Disco)+1;
		generarStructIPC(id_Disco,HANDSHAKE,&rInfoIPC44);
		enviarIPC(iSocketConectado,&rInfoIPC44);
		InfoIPC rInfoIPC;
		recibirIPC(iSocketConectado,&rInfoIPC);
		free(rInfoIPC44.payload);

		if(rInfoIPC.payLoadDescriptor== HSOK){
		
			char *sAux=(char *)malloc(20);

			InfoIPC rInfoIPC2;
			intacad(glChs.cilindros,sAux);
			rInfoIPC2.payLoadLength=strlen(sAux)+1;
			generarStructIPC(sAux,NUEVO_DA,&rInfoIPC2);
			enviarIPC(iSocketConectado,&rInfoIPC2);
			free(rInfoIPC2.payload);
			
			InfoIPC rInfoIPC3;
			intacad(glChs.cabezal,sAux);
			rInfoIPC3.payLoadLength=strlen(sAux)+1;
			generarStructIPC(sAux,NUEVO_DA,&rInfoIPC3);
			enviarIPC(iSocketConectado,&rInfoIPC3);
			free(rInfoIPC3.payload);
			
			InfoIPC rInfoIPC4;
			intacad(glChs.sectores, sAux);
			rInfoIPC4.payLoadLength=strlen(sAux)+1;
			generarStructIPC(sAux,NUEVO_DA,&rInfoIPC4);
			enviarIPC(iSocketConectado,&rInfoIPC4);
			free(rInfoIPC4.payload);
			
			free(sAux);

			InfoIPC rInfoIPC5;
			recibirIPC(iSocketConectado,&rInfoIPC5);
			
			
			switch(rInfoIPC5.payLoadDescriptor)
			{
				case DA_INCOMPATIBLE:
						printf("PPD incompatible\n");
						return 0;
						break;
		
				case DA_CONECTADO_CORRECTAMENTE:
					printf("El PPD se conecto correctamente \n");
					break;

				default:
					printf("No se recibio msj valido \n");
					return 0;
					break;
					
			}
			free(rInfoIPC5.payload);
		}

		free(rInfoIPC.payload);
		
	
		 
		while(1)
		{
			
			struct ListaIDdescriptors * NodoDescriptores = (struct ListaIDdescriptors *)malloc(sizeof(struct ListaIDdescriptors));	
	
			/*Se recibe numero de pedido*/
			InfoIPC rInfoIPC2;
			/*Se desconecta RAID*/
			if(recibirIPC(iSocketConectado,&rInfoIPC2)<0){	
				printf("Se cayo RAID \n");
				close(Sock_consola);
				close(iSocketConectado);
				return -1;
			}
	  
	
			
			if(strchr(rInfoIPC2.payload, ';') != NULL)
			{
				strcpy(buffer, (char *) strtok_r(rInfoIPC2.payload, ";",&brkt));
				strcpy(buffer_id, (char *) strtok_r(buffer, ",",&brkt));
				strcpy(buffer_sect, (char *) strtok_r(NULL, "\r\n\0",&brkt));
			}
			else
				continue;
		
		
			sector_num = atoi(buffer_sect);
		
			strcpy(NodoDescriptores->sDescriptorID_delPedido,buffer_id);
			NodoDescriptores->sector=sector_num;
		
		
			/*Se completa el nodo*/
			intacad(iSocketConectado,sSocket);
			strcpy(NodoDescriptores->sSocketPorElCualResponder,sSocket);
			NodoDescriptores->Sgt = NULL;
			NodoDescriptores->Ant = NULL;        
			
			
			if((rInfoIPC2.payLoadDescriptor == READ_SECTOR_REQUEST)||(rInfoIPC2.payLoadDescriptor == READ_SECTORSYNC_REQUEST))
			{
				log_info(logFile, "CONNECT", "LLEGO PEDIDO.\nTipo:Lectura\nSector: %i", sector_num);
				strcpy(NodoDescriptores->data,"");
				NodoDescriptores->operacion=0;
			}
			
			if((rInfoIPC2.payLoadDescriptor == WRITE_SECTOR_REQUEST)||(rInfoIPC2.payLoadDescriptor == WRITE_SECTORSYNC_REQUEST))
			{
				log_info(logFile, "CONNECT", "LLEGO PEDIDO.\nTipo:Escritura\nSector: %i", sector_num);
				memcpy(NodoDescriptores->data , (rInfoIPC2.payload) + strlen(buffer_id) + 1 + strlen(buffer_sect) + 1, 512);
				NodoDescriptores->operacion=1;
			}
			
			if((rInfoIPC2.payLoadDescriptor == READ_SECTORSYNC_REQUEST)){
				NodoDescriptores->operacion=2;

			}
			if((rInfoIPC2.payLoadDescriptor == WRITE_SECTORSYNC_REQUEST)){
				NodoDescriptores->operacion=3;
			}
			
			if(ALG==FSCAN)
			{
				if(activaEnAtencion)
				{	
		
					if(pthread_mutex_lock(&mutex2)!=0){
						perror("pthread_mutex_lock");
						exit(EXIT_FAILURE);
					}

					insertarSegunAlgoritmo(&NodoDescriptores, &cola2.activacabeza, &cola2.activacola,posicionCabezal,1);
					
					if(pthread_mutex_unlock(&mutex2)!=0){
						perror("pthread_mutex_unlock");
						exit(EXIT_FAILURE);
					}
				
				}
				else
				{	
			
					if(pthread_mutex_lock(&mutex)!=0){
						perror("pthread_mutex_lock");
						exit(EXIT_FAILURE);
					}
					
					insertarSegunAlgoritmo(&NodoDescriptores, &cola2.activacabeza, &cola2.activacola,posicionCabezal,1);
					sem_post(&pedidos);
			
					if(pthread_mutex_unlock(&mutex)!=0){
						perror("pthread_mutex_unlock");
						exit(EXIT_FAILURE);
					}	
				}
			
			}
			
			
			
			if(ALG==CLOOK)
			{
			
				
				if(pthread_mutex_lock(&mutex)!=0){
					perror("pthread_mutex_lock");
					exit(EXIT_FAILURE);
				}
			
				/*imprimirCola(cola2.activacabeza);*/
				/*printf("quiero insertar sector NRO %i \n",NodoDescriptores->sector);*/
				insertarSegunAlgoritmo(&NodoDescriptores, &cola2.activacabeza, &cola2.activacola,posicionCabezal,0);
				sem_post(&pedidos);
				
				if(pthread_mutex_unlock(&mutex)!=0){
					perror("pthread_mutex_unlock");
					exit(EXIT_FAILURE);
				}
			}	
		
			free(rInfoIPC2.payload);
		}
		
		cerrarSocket(iSocketConectado);
	}	
	
	if(MODO==LISTEN){	


		int rc=0;
		numeroPedido=1;
		iSocketEscuchaConexiones  = PrepararSocket (atoi(obtenerValor("puerto")),obtenerValor("ip"));   
		escuchar(iSocketEscuchaConexiones,10000); 
		printf("iSocketEscuchaConexiones  %i \n",iSocketEscuchaConexiones);
		
		int maxSocket;
		fd_set set_socketsHiloPrincipal;
		FD_ZERO(&set_socketsHiloPrincipal);
		FD_SET(iSocketEscuchaConexiones, &set_socketsHiloPrincipal);
		iMayorSocket = iSocketEscuchaConexiones;

		listaPFS *ListaClientes= NULL, *ListaClientes_Ult= NULL;
		listaPFS *pAuxCliente = NULL;

		while(1)
		{

			FD_SET(iSocketEscuchaConexiones, &set_socketsHiloPrincipal);
			iMayorSocket = iSocketEscuchaConexiones;

			pAuxCliente = ListaClientes;
			while(pAuxCliente != NULL)
			{
				FD_SET(pAuxCliente->iSocket , &set_socketsHiloPrincipal);
				if(pAuxCliente->iSocket > iMayorSocket)
					iMayorSocket = pAuxCliente->iSocket;
				pAuxCliente = pAuxCliente->Sgt;
			}


			select(iMayorSocket + 1,&set_socketsHiloPrincipal, NULL, NULL, NULL);


			/*ACEPTO CONEXIONES DE CLIENTES FSS*/
			if( FD_ISSET(iSocketEscuchaConexiones, &set_socketsHiloPrincipal ) > 0 )
			{

				listaPFS *nuevoPFS = (listaPFS *) malloc (sizeof(listaPFS));

				int iSocketPFS_temporal;
				if((iSocketPFS_temporal = accept(iSocketEscuchaConexiones,(struct sockaddr*)&cliente,&address_size))== -1)
					return ERRORACCEPT;

				nuevoPFS->iSocket = iSocketPFS_temporal;
				nuevoPFS->flag_cerrar = 0;

				InfoIPC rInfoIPC;
				printf("Se conecto el cliente  %i \n",nuevoPFS->iSocket);
				recibirIPC(nuevoPFS->iSocket,&rInfoIPC);
				free(rInfoIPC.payload);

				InfoIPC hsRInfoIPC;
				hsRInfoIPC.payLoadLength = 5;
				generarStructIPC("nada",HSOK,&hsRInfoIPC);
				enviarIPC(nuevoPFS->iSocket,&hsRInfoIPC);
				free(hsRInfoIPC.payload);


				agregarAListaDeClientes(&nuevoPFS, &ListaClientes, &ListaClientes_Ult);
				

			}


			/*RECIBO PEDIDOS DE ALGUN SOCKET CLIENTE FSS*/
			pAuxCliente = ListaClientes;
			while(pAuxCliente != NULL)
			{
				if( FD_ISSET(pAuxCliente->iSocket , &set_socketsHiloPrincipal ) > 0 ){
					break;
				}
				pAuxCliente = pAuxCliente->Sgt;
			}
			if(pAuxCliente != NULL)
			{
				listaPFS *pfs = (listaPFS *) pAuxCliente;
				char * sIDdescriptor_delPedido=(char *)malloc(20);
				char *sSocket=(char *)malloc(20);

				InfoIPC rInfoIPC;
				InfoIPC rInfoIPC2;
				int rc;

				while(1)
				{

					rc=0;
					rc = recibirIPC(pfs->iSocket,&rInfoIPC);
					if (rc < 0)
					{
						pfs->flag_cerrar = 1;
						break;
					}
					else
					{

						struct ListaIDdescriptors * NodoDescriptores = (struct ListaIDdescriptors *)malloc(sizeof(struct ListaIDdescriptors));

						if(pthread_mutex_lock(&mutexnumped)!=0)
						{
									perror("pthread_mutex_lock");
									exit(EXIT_FAILURE);
						}
						intacad(numeroPedido,sIDdescriptor_delPedido);
						if(pthread_mutex_unlock(&mutexnumped)!=0)
						{
									perror("pthread_mutex_unlock");
									exit(EXIT_FAILURE);
						}
						intacad(pfs->iSocket,sSocket);
						strcpy(NodoDescriptores->sDescriptorID_delPedido ,sIDdescriptor_delPedido);
						strcpy(NodoDescriptores->sSocketPorElCualResponder , sSocket);
						NodoDescriptores->Sgt = NULL;
						NodoDescriptores->Ant = NULL;


						if((rInfoIPC.payLoadDescriptor == READ_SECTOR_REQUEST) || (rInfoIPC.payLoadDescriptor == READ_SECTOR_REQUEST_LAST))
						{
							NodoDescriptores->operacion = 0;
							NodoDescriptores->sector=atoi(rInfoIPC.payload);

						}
						else if(rInfoIPC.payLoadDescriptor == WRITE_SECTOR_REQUEST)
						{

							NodoDescriptores->sector=atoi(rInfoIPC.payload);

							/*rInfoIPC.payLoadLength = 5;
							generarStructIPC("nada",RTA_WRITE_SECTOR_REQUEST,&rInfoIPC);
							enviarIPC(pfs->iSocket,&rInfoIPC);*/


							if(pthread_mutex_lock(&mutexnumped)!=0)
							{
										perror("pthread_mutex_lock");
										exit(EXIT_FAILURE);
							}
							intacad(numeroPedido,sIDdescriptor_delPedido);
							if(pthread_mutex_unlock(&mutexnumped)!=0)
							{
										perror("pthread_mutex_unlock");
										exit(EXIT_FAILURE);
							}
							intacad(pfs->iSocket,sSocket);
							strcpy(NodoDescriptores->sDescriptorID_delPedido , sIDdescriptor_delPedido);
							strcpy(NodoDescriptores->sSocketPorElCualResponder , sSocket);
							NodoDescriptores->operacion = 1;

							recibirIPC(pfs->iSocket,&rInfoIPC2);
							memset(NodoDescriptores->data,'\0',512);
							memcpy(NodoDescriptores->data, rInfoIPC2.payload, 512);


						}

						/*if(pthread_mutex_lock(&mutex)!=0){
							printf("pthread_mutex_lock\n");
							exit(EXIT_FAILURE);
						}

						insertarSegunAlg(&NodoDescriptores, &cola2.activacabeza, &cola2.activacola,&cola2.segundaPasadaActiva,posicionCabezal,0);
						*//*AgregarAColaDePedidosADisco(&NodoDescriptores, &cola2.activacabeza, &cola2.activacola);*/
						/*sem_post(&pedidos);

						imprimirCola(cola2.activacabeza);

						if(pthread_mutex_unlock(&mutex)!=0){
							printf("pthread_mutex_unlock\n");
							exit(EXIT_FAILURE);
						}*/



						if(ALG==FSCAN)
						{
							if(activaEnAtencion)
							{

								if(pthread_mutex_lock(&mutex2)!=0){
									perror("pthread_mutex_lock");
									exit(EXIT_FAILURE);
								}
								if(pthread_mutex_lock(&mutex3)!=0){
									perror("pthread_mutex_unlock");
									exit(EXIT_FAILURE);
								}
								insertarSegunAlg(&NodoDescriptores, &cola2.pasivacabeza, &cola2.pasivacola,&cola2.segundaPasadaPasiva,posicionCabezal,1);
								if(pthread_mutex_unlock(&mutex3)!=0){
									perror("pthread_mutex_unlock");
									exit(EXIT_FAILURE);
								}
								if(pthread_mutex_unlock(&mutex2)!=0){
									perror("pthread_mutex_unlock");
									exit(EXIT_FAILURE);
								}

							}
							else
							{

								if(pthread_mutex_lock(&mutex)!=0){
									perror("pthread_mutex_lock");
									exit(EXIT_FAILURE);
								}

								if(pthread_mutex_lock(&mutex3)!=0){
									perror("pthread_mutex_unlock");
									exit(EXIT_FAILURE);
								}
								insertarSegunAlg(&NodoDescriptores, &cola2.activacabeza, &cola2.activacola,&cola2.segundaPasadaActiva,posicionCabezal,1);
								if(pthread_mutex_unlock(&mutex3)!=0){
									perror("pthread_mutex_unlock");
									exit(EXIT_FAILURE);
								}
								sem_post(&pedidos);

								if(pthread_mutex_unlock(&mutex)!=0){
									perror("pthread_mutex_unlock");
									exit(EXIT_FAILURE);
								}
							}

						}



						if(ALG==CLOOK)
						{


							if(pthread_mutex_lock(&mutex)!=0){
								perror("pthread_mutex_lock");
								exit(EXIT_FAILURE);
							}

							if(pthread_mutex_lock(&mutex3)!=0){
								perror("pthread_mutex_unlock");
								exit(EXIT_FAILURE);
							}


							AgregarAColaDePedidosADisco(&NodoDescriptores, &cola2.activacabeza, &cola2.activacola);
							/*ordenarListaCSCAN(&cola2.activacabeza, &cola2.activacola,posicionCabezal);*/
							/*insertarSegunAlg(&NodoDescriptores, &cola2.activacabeza, &cola2.activacola,&cola2.segundaPasadaActiva,posicionCabezal,0);*/

							if(pthread_mutex_unlock(&mutex3)!=0){
								perror("pthread_mutex_unlock");
								exit(EXIT_FAILURE);
							}
							/*sem_post(&pedidos);*/

							/*imprimirCola(cola2.activacabeza);
*/
							if(pthread_mutex_unlock(&mutex)!=0){
								perror("pthread_mutex_unlock");
								exit(EXIT_FAILURE);
							}
						}


						if((rInfoIPC.payLoadDescriptor == READ_SECTOR_REQUEST_LAST) || (rInfoIPC2.payLoadDescriptor == SET_SECTORES_LAST))
						{
							break;
						}

						if(pthread_mutex_lock(&mutexnumped)!=0)
						{
									perror("pthread_mutex_lock");
									exit(EXIT_FAILURE);
						}
						numeroPedido++;
						if(pthread_mutex_unlock(&mutexnumped)!=0)
						{
									perror("pthread_mutex_unlock");
									exit(EXIT_FAILURE);
						}
					}
				}

				if(pfs->flag_cerrar == 1)
				{
					printf("Se desconecto el cliente %i \n", pfs->iSocket);		
					FD_CLR(pfs->iSocket, &set_socketsHiloPrincipal);				
					SacarDeLista_Clientes(&pfs, &ListaClientes, &ListaClientes_Ult);
					close(pfs->iSocket);
				}

				free(sIDdescriptor_delPedido);
				free(sSocket);
			}
		}
	}

	return 0;

}


void configToCHS()
{

	char* chsAux;
	chs resultadoChs;

	chsAux = (char*)malloc(strlen(obtenerValor("CHS"))+1);
	strcpy(chsAux,obtenerValor("CHS"));
	resultadoChs.cilindros = atoi(strtok(chsAux,","));
	resultadoChs.cabezal = atoi(strtok(NULL,","));
	resultadoChs.sectores = atoi(strtok(NULL,","));
	glChs = resultadoChs;

	free(chsAux);

}


chs getCHS()
{
	return glChs;
}





void intacad ( int n , char* cadena)

{	
    int j=0;
    int i=0;
	char aux;

	do
    {
		cadena[i] = (n % 10) + '0';    
		n=n/10;
		i++;

	}while (n > 0);

    cadena[i] = '\0';
    i--;

	while(i>j)
	{
		aux=cadena[i];
		cadena[i]=cadena[j];
		cadena[j]=aux;
		i--;
		j++;
	}
}


int	AgregarAColaDeConexionesPFS(listaPFS ** pnodo, listaPFS ** ListaDePFS)

{
	if((*ListaDePFS) == NULL)
	{
		(*pnodo)->Ant = NULL;
		(*pnodo)->Sgt = NULL;
		(* ListaDePFS) = (*pnodo);
	}	
	else
	{
		(*pnodo)->Ant = NULL;
		(*pnodo)->Sgt = (* ListaDePFS );
		(* ListaDePFS )->Ant = (*pnodo);
		(* ListaDePFS ) = (*pnodo);
	}
}





int removerConexionDeListaPFS(listaPFS ** pnodo, listaPFS ** ListaDePFS)

{
	listaPFS *actual;
	actual= *ListaDePFS;
	if(actual != NULL)
	{
		if(actual->iSocket == (*pnodo)->iSocket)
		{
			*ListaDePFS=(*ListaDePFS)->Sgt;
			free(actual);
			return 1;
		}
		
		listaPFS *anterior = *ListaDePFS;
		actual = actual->Sgt;
		
		while(actual != NULL)
		{
			if(actual->iSocket == (*pnodo)->iSocket)
				break;

			anterior = actual;
			actual = actual->Sgt;
		}

		if(actual != NULL)
		{
			anterior->Sgt = actual->Sgt;
			free(actual);
		}
	}
	return 1;
}



void * AtenderPFS(void * args)
{
	listaPFS *pfs = (listaPFS *) args;
	char * sIDdescriptor_delPedido=(char *)malloc(20);
	char *sSocket=(char *)malloc(20);
	
	InfoIPC rInfoIPC;
	InfoIPC rInfoIPC2;
	int rc;
	
	while(1)
	{
		
		rc=0;
		rc = recibirIPC(pfs->iSocket,&rInfoIPC);
		if (rc < 0)
		{
			pfs->flag_cerrar = 1;
			break;
		}
		else
		{
		
			struct ListaIDdescriptors * NodoDescriptores = (struct ListaIDdescriptors *)malloc(sizeof(struct ListaIDdescriptors));
		
			if(pthread_mutex_lock(&mutexnumped)!=0)
			{
						perror("pthread_mutex_lock");
						exit(EXIT_FAILURE);
			}
			intacad(numeroPedido,sIDdescriptor_delPedido); 
			if(pthread_mutex_unlock(&mutexnumped)!=0)
			{
						perror("pthread_mutex_unlock");
						exit(EXIT_FAILURE);
			}
			intacad(pfs->iSocket,sSocket);    
			strcpy(NodoDescriptores->sDescriptorID_delPedido ,sIDdescriptor_delPedido);  
			strcpy(NodoDescriptores->sSocketPorElCualResponder , sSocket);
			NodoDescriptores->Sgt = NULL;
			NodoDescriptores->Ant = NULL;      
				
				
			if((rInfoIPC.payLoadDescriptor == READ_SECTOR_REQUEST) || (rInfoIPC.payLoadDescriptor == READ_SECTOR_REQUEST_LAST))
			{
				NodoDescriptores->operacion = 0;
				NodoDescriptores->sector=atoi(rInfoIPC.payload);  
		
			}
			else if(rInfoIPC.payLoadDescriptor == WRITE_SECTOR_REQUEST)
			{
			
				NodoDescriptores->sector=atoi(rInfoIPC.payload);
				
				/*rInfoIPC.payLoadLength = 5;
				generarStructIPC("nada",RTA_WRITE_SECTOR_REQUEST,&rInfoIPC);
				enviarIPC(pfs->iSocket,&rInfoIPC);*/
				
				
				if(pthread_mutex_lock(&mutexnumped)!=0)
				{
							perror("pthread_mutex_lock");
							exit(EXIT_FAILURE);
				}
				intacad(numeroPedido,sIDdescriptor_delPedido); 
				if(pthread_mutex_unlock(&mutexnumped)!=0)
				{
							perror("pthread_mutex_unlock");
							exit(EXIT_FAILURE);
				}
				intacad(pfs->iSocket,sSocket);          
				strcpy(NodoDescriptores->sDescriptorID_delPedido , sIDdescriptor_delPedido);
				strcpy(NodoDescriptores->sSocketPorElCualResponder , sSocket);
				NodoDescriptores->operacion = 1;
				
				recibirIPC(pfs->iSocket,&rInfoIPC2);
				memset(NodoDescriptores->data,'\0',512);
				memcpy(NodoDescriptores->data, rInfoIPC2.payload, 512);
				
		
			}

			/*if(pthread_mutex_lock(&mutex)!=0){
				printf("pthread_mutex_lock\n");
				exit(EXIT_FAILURE);
			}

			insertarSegunAlg(&NodoDescriptores, &cola2.activacabeza, &cola2.activacola,&cola2.segundaPasadaActiva,posicionCabezal,0);
			*//*AgregarAColaDePedidosADisco(&NodoDescriptores, &cola2.activacabeza, &cola2.activacola);*/
			/*sem_post(&pedidos);

			imprimirCola(cola2.activacabeza);

			if(pthread_mutex_unlock(&mutex)!=0){
				printf("pthread_mutex_unlock\n");
				exit(EXIT_FAILURE);
			}*/
			


			if(ALG==FSCAN)
			{
				if(activaEnAtencion)
				{

					if(pthread_mutex_lock(&mutex2)!=0){
						perror("pthread_mutex_lock");
						exit(EXIT_FAILURE);
					}
					if(pthread_mutex_lock(&mutex3)!=0){
						perror("pthread_mutex_unlock");
						exit(EXIT_FAILURE);
					}
					insertarSegunAlg(&NodoDescriptores, &cola2.pasivacabeza, &cola2.pasivacola,&cola2.segundaPasadaPasiva,posicionCabezal,1);
					if(pthread_mutex_unlock(&mutex3)!=0){
						perror("pthread_mutex_unlock");
						exit(EXIT_FAILURE);
					}
					if(pthread_mutex_unlock(&mutex2)!=0){
						perror("pthread_mutex_unlock");
						exit(EXIT_FAILURE);
					}

				}
				else
				{

					if(pthread_mutex_lock(&mutex)!=0){
						perror("pthread_mutex_lock");
						exit(EXIT_FAILURE);
					}

					if(pthread_mutex_lock(&mutex3)!=0){
						perror("pthread_mutex_unlock");
						exit(EXIT_FAILURE);
					}
					insertarSegunAlg(&NodoDescriptores, &cola2.activacabeza, &cola2.activacola,&cola2.segundaPasadaActiva,posicionCabezal,1);
					if(pthread_mutex_unlock(&mutex3)!=0){
						perror("pthread_mutex_unlock");
						exit(EXIT_FAILURE);
					}
					sem_post(&pedidos);

					if(pthread_mutex_unlock(&mutex)!=0){
						perror("pthread_mutex_unlock");
						exit(EXIT_FAILURE);
					}
				}

			}



			if(ALG==CLOOK)
			{


				if(pthread_mutex_lock(&mutex)!=0){
					perror("pthread_mutex_lock");
					exit(EXIT_FAILURE);
				}

				if(pthread_mutex_lock(&mutex3)!=0){
					perror("pthread_mutex_unlock");
					exit(EXIT_FAILURE);
				}
				insertarSegunAlg(&NodoDescriptores, &cola2.activacabeza, &cola2.activacola,&cola2.segundaPasadaActiva,posicionCabezal,0);
				if(pthread_mutex_unlock(&mutex3)!=0){
					perror("pthread_mutex_unlock");
					exit(EXIT_FAILURE);
				}
				sem_post(&pedidos);

				imprimirCola(cola2.activacabeza);

				if(pthread_mutex_unlock(&mutex)!=0){
					perror("pthread_mutex_unlock");
					exit(EXIT_FAILURE);
				}
			}


			if((rInfoIPC.payLoadDescriptor == READ_SECTOR_REQUEST_LAST) || (rInfoIPC2.payLoadDescriptor == SET_SECTORES_LAST))
			{
				break;
			}
			
			if(pthread_mutex_lock(&mutexnumped)!=0)
			{
						perror("pthread_mutex_lock");
						exit(EXIT_FAILURE);
			}
			numeroPedido++;
			if(pthread_mutex_unlock(&mutexnumped)!=0)
			{
						perror("pthread_mutex_unlock");
						exit(EXIT_FAILURE);
			}
		}
	}
	
	if(pfs->flag_cerrar == 1)
		close(pfs->iSocket);
	
	free(sIDdescriptor_delPedido);
	free(sSocket);
	
	pthread_detach(pthread_self());
	
}
